package org.xmdl.silk.wrap;

import org.xmdl.silk.Expression;
import org.xmdl.silk.Operation;
import org.xmdl.silk.impl.OperationImpl;
import org.xmdl.silk.interpreter.Operator;
import org.xmdl.silk.visit.Visitor;

public class OperationWrap extends OperationImpl implements Expression, ExpressionWrap {

	private final Operation w;

	public OperationWrap(Operation w) {
		this.w = w;
		left = WrapUtils.expression(w.getLeft());
		right = WrapUtils.expression(w.getRight());
	}

	@Override
	public Expression getLeft() {
		return left;
	}

	@Override
	public Expression getRight() {
		return right;
	}

	@Override
	public void setLeft(Expression newLeft) {
		left = WrapUtils.expression(newLeft);
		w.setLeft(left);
	}

	@Override
	public void setRight(Expression newRight) {
		right = WrapUtils.expression(newRight);
		w.setRight(right);
	}

	@Override
	public String getOperator() {
		return w.getOperator();
	}

	@Override
	public void setOperator(String newOperator) {
		w.setOperator(newOperator);
	}

	public boolean accept(Visitor visitor) {
		if (visitor.visitEnter(this)) {
			Wrapped left = (Wrapped) getLeft();
			Wrapped right = (Wrapped) getRight();
			if (right == null) {
				left.accept(visitor);
			} else {
				Operator op = Operator.get(getOperator());
				if (visitor.visitEnter(op))
					if (left.accept(visitor) && visitor.visitLeave(op))
						right.accept(visitor);
			}
		}
		boolean result = visitor.visitLeave(this);
		return result;
	}

}
